-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Organization specific transcript credentials state #99
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muhammad-ammar This is looking good, a few miner changes.
The OrganizationTranscriptCredentialsState
model needs to available in Admin.
We also need to add video_source_language
in TranscriptPreference
model, FYI @muzaffaryousaf
edxval/models.py
Outdated
@@ -605,6 +605,48 @@ def __unicode__(self): | |||
return u'{course_id} - {provider}'.format(course_id=self.course_id, provider=self.provider) | |||
|
|||
|
|||
class OrganizationTranscriptCredentialsState(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be included in django admin panel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename it to TranscriptOrganizationCredentialsState
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are transcription credentials for an organization, So that's why I used the name OrganizationTranscriptCredentialsState
edxval/models.py
Outdated
return instance, created | ||
|
||
def __unicode__(self): | ||
return u'OrganizationTranscriptCredentialsState(org={}, provider={}, exists={})'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to show exists here
edxval/models.py
Outdated
@receiver(models.signals.pre_save, sender=OrganizationTranscriptCredentialsState) | ||
def validate_provider(sender, instance, **kwargs): # pylint: disable=unused-argument | ||
""" | ||
Validate that input provider value mus be one of TranscriptProviderType.CHOICES. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: value must be one
edxval/models.py
Outdated
|
||
|
||
@receiver(models.signals.pre_save, sender=OrganizationTranscriptCredentialsState) | ||
def validate_provider(sender, instance, **kwargs): # pylint: disable=unused-argument |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not validating providers anywhere else. Is this necessary here? Should we not add in other places too ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the cleanest way I found to validate provider
value before saving.
edxval/api.py
Outdated
@@ -143,6 +143,55 @@ def update_video_status(edx_video_id, status): | |||
video.save() | |||
|
|||
|
|||
def get_organization_transcript_credentials_state(org, provider=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename it to get_transcript_organization_credentials_state
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_3rd_party_transcript_credentials_state_for_org
would be good.
edxval/tests/test_api.py
Outdated
Verify that `get_organization_transcript_credentials_state` method works as expected | ||
""" | ||
state_info = api.get_organization_transcript_credentials_state(org=org, provider=provider) | ||
credentials_state = OrganizationTranscriptCredentialsState.objects.get(org=org, provider=provider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may not need to query db, if we add a exists
parameter in ddt. Something like :
@data(
{'org': 'edX', 'provider': 'Cielo24', 'exists': False},
{'org': 'edX', 'provider': '3PlayMedia', 'exists': False},
)
@unpack
def test_get_credentials_state(self, org, provider, exists):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need reading from db to verify that data received from api method is same as stored in db.
edxval/tests/test_api.py
Outdated
self.assertEqual(state_info['org'], credentials_state.org) | ||
self.assertEqual(state_info[provider], credentials_state.exists) | ||
|
||
def test_get_credentials_state_with_org_only(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test can be combined in above test with proper ddt
edxval/tests/test_api.py
Outdated
{'org': 'edX', 'provider': '3PlayMedia'}, | ||
) | ||
@unpack | ||
def test_get_credentials_state(self, org, provider): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also add a test if org does not match, what is expected result we should expect
edxval/tests/test_api.py
Outdated
org='edX', provider='3PlayMedia', exists=False | ||
) | ||
|
||
def assert_credential_state(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_credential_state
is not used anywhere
edxval/tests/test_api.py
Outdated
{'org': 'MAX', 'provider': '3PlayMedia', 'exists': True}, | ||
) | ||
@unpack | ||
def test_credentials_state_update(self, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also add a test the expected behaviour when org does not match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of update/create, new credentials state record will be created if org does not match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we missed this test for No org found
case?
814fbd8
to
3ab8aa5
Compare
@mushtaqak Feedback Addressed |
edxval/models.py
Outdated
""" | ||
Returns unicode representation of provider credentials state for an organization. | ||
|
||
NOTE: Message will look like below: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if this the best way ?
edxval/tests/test_api.py
Outdated
{'org': 'MAX', 'provider': '3PlayMedia', 'exists': True}, | ||
) | ||
@unpack | ||
def test_credentials_state_update(self, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we missed this test for No org found
case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muhammad-ammar This is almost ready. I haven't still seen the TranscriptPreference
model change that is required to store video_source_language
""" | ||
Returns unicode representation of provider credentials state for an organization. | ||
|
||
NOTE: Message will look like below: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if this is the best way to show record name ?
d186312
to
27ef47d
Compare
{'org': 'edx', 'provider': '3PlayMedia', 'exists': True}, | ||
) | ||
@unpack | ||
def test_credentials_state_update(self, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mushtaqak updated this test for an existing org.
edxval/models.py
Outdated
@@ -605,6 +605,55 @@ def __unicode__(self): | |||
return u'{course_id} - {provider}'.format(course_id=self.course_id, provider=self.provider) | |||
|
|||
|
|||
class OrganizationTranscriptCredentialsState(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we should probably use TimeStampedModel
to keep track of created and modified time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muhammad-ammar It is looking good except few minor concerns.
edxval/models.py
Outdated
@@ -605,6 +605,55 @@ def __unicode__(self): | |||
return u'{course_id} - {provider}'.format(course_id=self.course_id, provider=self.provider) | |||
|
|||
|
|||
class OrganizationTranscriptCredentialsState(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that the name should specify the inner relations as such --> I vote for ThirdPartyTranscriptCredentialsState
. Relation would be obvious by looking at its fields.
""" | ||
Update or create credentials state. | ||
""" | ||
instance, created = cls.objects.update_or_create( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice.
unique_together = ('org', 'provider') | ||
|
||
org = models.CharField(verbose_name='Course Organization', max_length=32) | ||
provider = models.CharField( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muhammad-ammar we don't need to verify provider on pre-save signal. Model will automatically raises Exception if the you try to save it with a Provider which is not in its choices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not happening. Model allows to save the incorrect data if I remove the signal.
edxval/models.py
Outdated
) | ||
|
||
|
||
@receiver(models.signals.pre_save, sender=OrganizationTranscriptCredentialsState) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this.
edxval/models.py
Outdated
edX has no 3PlayMedia credentials | ||
""" | ||
return u'{org} {state} {provider} credentials'.format( | ||
org=self.org, provider=self.provider, state='has' if self.exists else 'has no' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't have
instead of has no
sounds better.
edxval/api.py
Outdated
provider (unicode): transcript provider | ||
|
||
Returns: | ||
dict: contains the information regarding organization's transcript provider credentials |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
organization's --> organization-specific
edxval/api.py
Outdated
{ | ||
'org': 'edX', | ||
'Cielo24': False, | ||
'3PlayMedia': True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muhammad-ammar this is also an idea, can we just change our model like this?
org
has_3play_creds
has_cielo_creds
edxval/api.py
Outdated
provider (unicode): transcript provider | ||
exists (bool): state of credentials | ||
""" | ||
OrganizationTranscriptCredentialsState.update_or_create(org, provider, exists) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return something? like rerialized updated or created record?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need, looks good.
edxval/api.py
Outdated
return credentials_state_info | ||
|
||
|
||
def update_organization_transcript_credentials_state(org, provider, exists): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update_3rd_party_transcript_credentials_state_for_org
edxval/tests/test_api.py
Outdated
Verify that `update_organization_transcript_credentials_state` method works as expected | ||
""" | ||
api.update_organization_transcript_credentials_state( | ||
org=kwargs['org'], provider=kwargs['provider'], exists=kwargs['exists'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simpler: api.update_organization_transcript_credentials_state(**kwargs)
class Meta: | ||
unique_together = ('org', 'provider') | ||
|
||
org = models.CharField(verbose_name='Course Organization', max_length=32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
max_length=50
to be consistent with edx-pipeline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been done in #102
27ef47d
to
2b85892
Compare
@@ -0,0 +1,28 @@ | |||
# -*- coding: utf-8 -*- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would also need to change as 0006 migration has been renamed in #102
2b85892
to
f5182f8
Compare
@muzaffaryousaf @Qubad786 @mushtaqak Feedback addressed. Whoever is using this needs to update the hash and api function names. |
@Qubad786 @mushtaqak can you guys finalize this PR as per the usage in our other branches. |
@mushtaqak @Qubad786 This needs review from you guys. |
edxval/models.py
Outdated
|
||
NOTE: Message will look like below: | ||
edX has Cielo24 credentials | ||
edX has no 3PlayMedia credentials |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: edX doesn't have 3PlayMedia credentials
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great 👍! I've just a single concern about the validation.
edxval/models.py
Outdated
Update or create credentials state. | ||
""" | ||
instance, created = cls.objects.update_or_create( | ||
org=org, provider=provider, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: proper line break for kwargs
.
edxval/models.py
Outdated
Validate that input provider value must be one of TranscriptProviderType.CHOICES. | ||
""" | ||
if instance.provider not in dict(TranscriptProviderType.CHOICES).keys(): | ||
raise ValidationError('Invalid transcript provider value') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muhammad-ammar I think its alright to remove this signal. We can validate it in api utils which are responsible for creating an actual state record in db, Or even we may not validate as its getting validated from the view which is calling val's api.
Also, if we look at Video
model, status
is just CharField
without choices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@muhammad-ammar Looking great, just one thing to use TimeStampedModel
and may be a better name for migration ?
@@ -0,0 +1,28 @@ | |||
# -*- coding: utf-8 -*- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should rename the migration to better name ? just as we did for 006_
edxval/models.py
Outdated
@@ -612,6 +612,55 @@ def __unicode__(self): | |||
return u'{course_id} - {provider}'.format(course_id=self.course_id, provider=self.provider) | |||
|
|||
|
|||
class ThirdPartyTranscriptCredentialsState(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use TimeStampedModel
3b8222c
to
27e9af9
Compare
@mushtaqak @Qubad786 Feedback addressed. |
@mushtaqak @Qubad786 Feedback addressed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one concern.
edxval/api.py
Outdated
credential.provider: credential.exists | ||
for credential in ThirdPartyTranscriptCredentialsState.objects.filter(**query_filter) | ||
} | ||
except ThirdPartyTranscriptCredentialsState.DoesNotExist: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filter won't raise ThirdPartyTranscriptCredentialsState.DoesNotExist
. We are good without try: except..
here.
I think just return the following would work.
{
credential.provider: credential.exists
for credential in ThirdPartyTranscriptCredentialsState.objects.filter(**query_filter)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Good to go
3e1b105
to
2222670
Compare
6395732
to
0a9c823
Compare
EDUCATOR-1376
2222670
to
adc7696
Compare
EDU-1369
Remove subtitles code from VAL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 once we increment the VAL version
…/edx-val into ammar/org-specific-credentials-state
EDUCATOR-1376